/**
 * Created by 陈文豪 on 2017/1/9.
 */
import {Injectable} from '@angular/core';
import {Md5} from "ts-md5/dist/md5";
import {Subject} from "rxjs";
import * as GLOBAL from "@core/globals/globals.service";
import {StatusCodeService} from "@shared/service/status-code/status-code.service";
import {DateStoreVO, PresentData} from "@interface/index";
import {DateStoreService, getDateTimeStamp} from "@shared/service/date-store/date-store.service";

function getWindow(): any {
  return window;
}

@Injectable()
export class ToolsService {
  public loadingRunning = false;
  public toastRunning = false;
  scrollTopSource: Subject<any> = new Subject<any>();
  scrollTop$ = this.scrollTopSource.asObservable();

  constructor(
    public code: StatusCodeService,
    public dateStore: DateStoreService
  ) { }

  get nativeWindow(): any {
    return getWindow();
  }

  setTitle(title: string) {
    // document.getElementsByClassName('seed-toolbar-title')[0]
    //   .innerHTML = title;
    if (title) {
      document.title = title;
    }
  }

  scrollTop() {
    this.scrollTopSource.next();
  }

  /*set(target, states) {
    target = states;
  }

  get(target) {
    return target;
  }
*/

  /**
   * @description MD5加密
   * @param key 加密的内容
   * @returns {string} md5加密后大写的内容
   */
  encryption (key: string) {
    const keys = Md5.hashStr(key).toString();

    return keys.toLowerCase();
  }

  /**
   * 格式化需要调用post请求需要的from数据
   * @param value
   * @returns {string} 格式化后数据的格式{email=example@gmail.com&password=abcd}
   */
  param(value) {
    return Object.keys(value).map((key) => {
      let URI: string;
      if (value[key] != null) {
        URI = encodeURIComponent(key) + '=' + encodeURIComponent(value[key]);
      }
      return URI;
    }).join('&');
  }

  /**
   * 格式化需要调用post请求需要的特殊from数据
   * 配合build
   * @param value
   * @returns {string} 格式化后数据的格式{email=example@gmail.com&password=abcd}
   */

  params(value) {
    let s = [],
      add = function (key, value) {
        s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
      };
    if (Array.isArray(value)) {
      for (const v in value) {
        add(v, value[v]);
      }
    } else {
      for (const prefix in value) {
        this.build(prefix, value[prefix], add);
      }
    }

    return s.join("&");
  }

  build(prefix, obj, add) {
    if (Array.isArray(obj)) {
      for (let i = 0; i < obj.length; i++) {
        this.build(prefix + "[" + (typeof obj[i] === "object" ? i : "") + "]", obj[i], add);
      }
    } else if (typeof (obj) === "object") {
      for (const name in obj) {
        this.build(prefix + "." + name, obj[name], add);
      }
    } else {
      add(prefix, obj);
    }
  }

  /**
   * @description 调用此方法显示loading
   * @param content 显示的内容
   * @param duration 持续的时间,默认为5s
   */
  showLoading(duration: number = 5000) {
    const element = document.querySelector('.loading');
    if (!element) {
      const loading = document.createElement('div');
      loading.className = 'loading';
      loading.innerHTML = '<img src="../../../../assets/icon/loading2.svg">';
      document.body.appendChild(loading);
    }

  }

  /**
   * @description 关闭loading
   */
  hideLoading() {
    const element = document.querySelector('.loading');
    if (element) {
      document.body.removeChild(element);
    }
  }

  /**
   * @description 调用此方法显示toast
   * @param message 提示语
   * @param duration 持续时间
   */
  showToast(message: string, duration: number = 1500) {
    const element = document.querySelector('.toast');
    if (!element) {
      let toast = document.createElement('div');
      toast.className = 'toast';
      toast.innerHTML = message;
      document.body.appendChild(toast);
    }
    setTimeout(function () {
      let element = document.querySelector('.toast');
      if (element) {
        document.body.removeChild(element);
      }
    }, duration);
  }

  /**
   * @Description 弹出框
   * @param message  // 提示语
   * @param style  // 不为0的数字不会跳到下载页面，默认跳到下载页面
   * @param confirmCallback  // 取消回调函数
   * @param cancelCallback  // 确认的回调
   */
  presentConfirm(message: string, style?: number, confirmCallback?, cancelCallback?, leftText?, rightText?) {
    if (document.getElementsByClassName('seed-confirm-bg').length > 0 || document.getElementsByClassName('seed-present-bg').length > 0) {
      return;
    }
    let lText = leftText || '取 消';
    let rText = rightText || '确 定';
    let confirmBg = document.createElement('div');
    confirmBg.className = 'seed-confirm-bg';
    let bodyTop = document.getElementsByTagName('body')[0];
    let seedConfirm = document.createElement('div');
    seedConfirm.className = 'seed-confirm';

    seedConfirm.innerHTML = `
          <div class="seed-confirm-box">
            <div class="confirm-title"></div>
            <div class="confirm-button">
              <div class="confirm-no">${lText}</div>
              <div class="confirm-yes">${rText}</div>
            </div>
          </div>
        `;
    bodyTop.appendChild(confirmBg);
    bodyTop.appendChild(seedConfirm);
    document.getElementsByClassName('confirm-title')[0].innerHTML = message;
    const removeChild = function (event) {
      if (style) {
        if (event.target.className === 'confirm-yes') {
          if (confirmCallback) {
            confirmCallback();
          }
        } else {
          if (cancelCallback) {
            cancelCallback();
          }
        }
      } else {
        if (event.target.className === 'confirm-yes') {
          window.open(GLOBAL.DOWNLOAD_APP_PATH);
        }
      }
      bodyTop.removeChild(confirmBg);
      bodyTop.removeChild(seedConfirm);

       //  confrimCancle.removeEventListener('click',removeChild,false);
       //  confrimYes.removeEventListener('click',removeChild,false);
    };
    let confrimCancle = document.getElementsByClassName('confirm-no')[0];
    let confrimYes = document.getElementsByClassName('confirm-yes')[0];
    confrimCancle.addEventListener('click', removeChild, false);
    confrimYes.addEventListener('click', removeChild, false);
  }

  /**
   * @Description 弹出框
   * @param data = {
   *                title ?: string,  // 标题
   *                message ?: Array<string> | string, //  内容，若是数组则遍历分行显示
   *                cancelBtn ?: boolean, // 有没有取消按钮
   *                confirmText? : string, // 右边确定键上的文字
   *                cancelText?: string, // 左边按钮上的文字（cancelBtn属性需要设置为true）
   *                }
   *  @reutrn promise: true | false
   */
  present(data: string | PresentData): Promise<boolean> {
    return new Promise((resolve, reject) => {

      if (document.getElementsByClassName('seed-confirm-bg').length > 0) {
        resolve(false);
      }

      let confirmBg = document.createElement('div');
      confirmBg.className = 'seed-confirm-bg';
      let bodyTop = document.getElementsByTagName('body')[0];
      let seedConfirm = document.createElement('div');
      seedConfirm.className = 'seed-present';

      let titleDiv = '';
      let msgDiv = '';
      let btnDiv = '';
      if (typeof data === 'string') {  // 只传字符串
        msgDiv = `<div class="present-title">${data}</div>`;
        btnDiv = `
                  <div class="present-button">
                    <div class="present-yes">确定</div>
                  </div>
                  `;
      } else {  // data是对象
        if (!!data.title) {
          titleDiv = `<div class="present-title">${data.title}</div>`;
        }

        if (!!data.message) {
          let msgArr = [], msgStr = '';
          if (typeof data.message === 'string') {
            msgArr = [data.message];
          } else {
            msgArr = data.message;
          }
          msgArr.forEach(e => {
            msgStr += `<p class="present-each-msg">${e}</p>`;
          });
          msgDiv = `<div class="present-msg">${msgStr}</div>`;
        }

        if (data.cancelBtn) {
          btnDiv = `
                    <div class="present-button has-cancel">
                      <div class="present-no">${data.cancelText ? data.cancelText : '取消'}</div>
                      <div class="present-yes">${data.confirmText ? data.confirmText : '确定'}</div>
                    </div>
                    `;
        } else {
          btnDiv = `
                    <div class="present-button">
                      <div class="present-yes">${data.confirmText ? data.confirmText : '确定'}</div>
                    </div>
                    `;
        }
      }

      seedConfirm.innerHTML = `
            <div class="seed-present-box">
              ${titleDiv ? titleDiv : ''}
              ${msgDiv ? msgDiv : ''}
              ${btnDiv ? btnDiv : ''}
            </div>
          `;
      bodyTop.appendChild(confirmBg);
      bodyTop.appendChild(seedConfirm);
      const removeChild = function (event) {
        if (event.target.className === 'present-yes') {
          resolve(true);
        } else {
          resolve(false);
        }
        bodyTop.removeChild(confirmBg);
        bodyTop.removeChild(seedConfirm);
      };
      let confrimCancle;
      let cancelBtn = document.getElementsByClassName('present-no');
      if (cancelBtn.length > 0) {
        confrimCancle = cancelBtn[0];
        confrimCancle.addEventListener('click', removeChild, false);
      }
      let confrimYes = document.getElementsByClassName('present-yes')[0];
      confrimYes.addEventListener('click', removeChild, false);
    });
  }


  showStatusCodeMsg(codeName, duration: any = 1500) {
    const message = this.code.getStatusCode(codeName);
    this.showToast(message, duration);
  }

   // 设置对象为数组
  setArray(val) {
    return Array.from(val);
  }

  setKeys(value) {
    let arr = [];
    let keys = Object.keys(value);
    keys.map((item, i) => {
      arr.push({[item]: value[item]});
    });
    value = arr;
    return value;
  }

   // 回到顶部
  onBackToTop() {
    window.scrollTo(0, 0);
  }

  /**
   * @description 判断对象是否为空，如果为空返回true,反之false，
   * 用于ngIf判断显示或者隐藏
   * @param obj
   * @returns {boolean}
   */
  isEmptyObject(obj) {
    return (Object.keys(obj).length === 0);
  }

  /**
   *
   * @param target 需要push的数组
   * @param data 需要遍历的数组list
   * @returns {string[]}
   */
 /* forAssistant(target: string[], data: string[]) {
    if (!target || !data) {
      return;
    }
    for (let i = 0; i < data.length; i++) {
      target.push(data[i]);
    }
    return target;
  }*/

  forAssistant(target: string[], data: string[]) {
    if (!target || !data) {
      return;
    }
    target.push.apply(target, data);
    // or target.push(...data);
    return target;
  }

  /**
   * @description 返回设备屏幕的宽度和高度
   * @returns {{width: any, height: any}}
   */
 /* getWindowSize() {
    let winWidth: number,
      winHeight: number;

    if (window.innerWidth) {
      winWidth = window.innerWidth;
    } else if ((document.body) && (document.body.clientWidth)) {
      winWidth = document.body.clientWidth;
    }

    if (window.innerHeight) {
      winHeight = window.innerHeight;
    } else if ((document.body) && (document.body.clientHeight)) {
      winHeight = document.body.clientHeight;
    }

    if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth) {
      winHeight = document.documentElement.clientHeight;
      winWidth = document.documentElement.clientWidth;
    }

    return {
      'width': winWidth,
      'height': winHeight
    };
  }*/


  getWindowSize() {
    return {
      'width': window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
      'height': window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
    };
  }
  /**
   * @description 取两个元素中最小的值
   * @author @chenwenhao576
   * @date 20170913
   * @param val1
   * @param val2
   * @returns {number}
   */
  Min(val1, val2) {
    return Math.min(val1, val2);
  }

  /**
   * @description 取两个元素中最大的值
   * @author @chenwenhao576
   * @date 20170913
   * @param val1
   * @param val2
   * @returns {number}
   */
  Max(val1, val2) {
    return Math.max(val1, val2);
  }

  replaceVideoUrl(val, limit = 320, second = 10) {
    let url = val.replace('/f/', '/fv/');
    const index = url.indexOf('.mp4');
    url = url.replace('.mp4', '');
    let result = url.substring(0, index);
    result = url + `_mp4_${second}_${limit}x0.jpg`;
    return result || null;
  }

  /**
   * @description 格式化时间
   * @author @lihao1157
   * @date 20171114
   * @param date
   * @param fmt
   * @returns {date}
   */
  formartDate(date: Date, fmt: string) {
    const o = {
      "M+": date.getMonth() + 1,                         // 月份
      "d+": date.getDate(),                              // 日
      "h+": date.getHours(),                             // 小时
      "m+": date.getMinutes(),                           // 分
      "s+": date.getSeconds(),                           // 秒
      "q+": Math.floor((date.getMonth() + 3) / 3),   // 季度
      "S": date.getMilliseconds()                        // 毫秒
    };

    if (/(y+)/.test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    }
    for (const k in o)
      if (new RegExp("(" + k + ")").test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
      }
    return fmt;
  }

  ua() {
    return {
      iOS5: null != navigator.userAgent.match(/OS 5_/i),
      isIos9: null != navigator.userAgent.match(/OS 9_/i),
      isIphone: !!navigator.userAgent.match(/iphone/gi),
      isIos: !!navigator.userAgent.match(/iphone|ipad/gi),
      isIpad: !!navigator.userAgent.match(/ipad/gi),
      isWinPhone: !!navigator.userAgent.match(/Windows Phone/gi),
      isWeixin: !!navigator.userAgent.match(/MicroMessenger/gi),
      isSogou: !!navigator.userAgent.match(/sogoumobilebrowser/gi),
      isUCBrowser: !!navigator.userAgent.match(/UCBrowser/gi),
      isQQBrowser: !!(navigator.userAgent.match(/MQQBrowser/gi) && !navigator.userAgent.match(/MicroMessenger/gi)),
      isBaidu: !!navigator.userAgent.match(/baidu/gi),
      isTrident: navigator.userAgent.indexOf("Trident") > -1,
      isPresto: navigator.userAgent.indexOf("Presto") > -1,
      isWebKit: navigator.userAgent.indexOf("AppleWebKit") > -1,
      isGecko: navigator.userAgent.indexOf("Gecko") > -1 && navigator.userAgent.indexOf("KHTML") === -1,
      isMobile: !!navigator.userAgent.match(/AppleWebKit.*Mobile.*/),
      isTIOS: !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
      isAndroid: navigator.userAgent.indexOf("Android") > -1 || navigator.userAgent.indexOf("Adr") > -1,
      iswebApp: navigator.userAgent.indexOf("Safari") === -1,
      isQQ: !!navigator.userAgent.match(/QQ\//i),
      isIosSafari: function () {
        const ua = navigator.userAgent;
        const reg = /applewebkit\/\d+(\.\d+)*\d+\s*\(KHTML,\s*like\s*Gecko\)\s*version\/\d+(\.\d+)*\.\d+\s*mobile\/\d+\w\d+\s*safari\/\d+(\.\d+)*\.\d+$/i;
        const isLiebao = window.hasOwnProperty("isLBBrowser");
        return reg.test(ua) && !isLiebao;
      }()
    };
  }

  // /**
  //  * @description 设置某天的 0 点 0 分 0 秒 0 毫秒
  //  * @author 欧晓辉
  //  * @return string: today || yesterday || month || lastMonth || week || lastWeek ||free
  //  */
  // setZeroTime(Date: Date) {
  //   let temp = Date;
  //   temp.setHours(0);
  //   temp.setMinutes(0);
  //   temp.setSeconds(0);
  //   temp.setMilliseconds(0);
  //   return temp;
  // }

  /**
   * @description 获取时间比较结果
   * @author 欧晓辉
   * @return string: today（今天） || yesterday （昨天）
   *        || someday (某天) || month（本月）
   *        || lastMonth（上月） || week（本周）
   *        || lastWeek（上周） || year（今年）
   *        || lastYear（去年） ||free（自由时间）
   */
  checkTime(startTime: Date, endTime?: Date): string {
    // const startTimeYear = startTime.getFullYear();
    // const startTimeMon = startTime.getMonth();
    // const startTimeDay = startTime.getDate();
    // const dateStore = this.dateStore.getDate;
    const startTimeStamp = getDateTimeStamp(startTime.getFullYear(), startTime.getMonth(), startTime.getDate());
    const nowTime = this.dateStore.getTimeStampStore;
    if (!endTime) {
      if (startTimeStamp === nowTime.today) {
        return 'today';
      } else if (startTimeStamp === nowTime.yesterday) {
        return 'yesterday';
      } else {
        return 'someday';
      }
    }
    if (endTime) {
      const endTimeStamp = getDateTimeStamp(endTime.getFullYear(), endTime.getMonth(), endTime.getDate());
      if (startTimeStamp === nowTime.yearStartDate && endTimeStamp === nowTime.yearEndDate) {
        return 'year';
      } else if (startTimeStamp === nowTime.lastYearStartDate && endTimeStamp === nowTime.lastYearEndDate) {
        return 'lastYear';
      } else if (startTimeStamp === nowTime.monthStartDate && endTimeStamp === nowTime.monthEndDate) {
        return 'month';
      } else if (startTimeStamp === nowTime.lastMonthStartDate && endTimeStamp === nowTime.lastMonthEndDate) {
        return 'lastMonth';
      } else if (startTimeStamp === nowTime.weekStart && endTimeStamp === nowTime.weekEnd) {
        return 'week';
      } else if (startTimeStamp === nowTime.LastWeekStart && endTimeStamp === nowTime.LastWeekEnd) {
        return 'lastWeek';
      } else {
        return 'free';
      }
    }
  }

  /**
   * 获取指定时间的
   * @param type
   */
  getRankTime(type) {
    const nowDate = this.dateStore.getDate;
    switch (type) {
      case 'today': // 今天
        return [new Date(nowDate.year, nowDate.month, nowDate.today) , null];
      case 'yesterday': // 昨天
        return [new Date(nowDate.year, nowDate.month, nowDate.today - 1) , null];
      case 'month':  // 本月
        return [new Date(nowDate.year, nowDate.month, 1) , new Date(nowDate.year, nowDate.month, nowDate.MonthLastDate)];
      case 'lastMonth':  // 上月
        return [new Date(nowDate.year, nowDate.month - 1, 1) , new Date(nowDate.year, nowDate.month - 1, nowDate.lastMonthLastDate)];
      case 'week':  // 本周
        if (nowDate.weekDay === 0) {
          return [
            new Date(nowDate.year, nowDate.month, nowDate.today - 6),
            new Date(nowDate.year, nowDate.month, nowDate.today)];
        }else {
          return [
            new Date(nowDate.year, nowDate.month, nowDate.today - nowDate.weekDay + 1) ,
            new Date(nowDate.year, nowDate.month, nowDate.today + 7 - nowDate.weekDay)
          ];
        }
      case 'lastWeek':  // 上周
        if (nowDate.weekDay === 0) {
          return [
            new Date(nowDate.year, nowDate.month, nowDate.today - 13),
            new Date(nowDate.year, nowDate.month, nowDate.today - 7)
          ];
        }else {
          return [
            new Date(nowDate.year, nowDate.month, nowDate.today - nowDate.weekDay + 1 - 7),
            new Date(nowDate.year, nowDate.month, nowDate.today + 7 - nowDate.weekDay - 7)
          ];
        }
      case 'year':  // 今年
        return [
          new Date(nowDate.year, 0, 1),
          new Date(nowDate.year, 11, 31)
        ];
      case 'lastYear':  // 去年
        return [
          new Date(nowDate.year - 1, 0, 1),
          new Date(nowDate.year - 1, 11, 31)
        ];
    }
  }

  /**
   * @description 时间拼成字符串
   * @author 欧晓晖
   * @date 2017/08/25
   * @param startDate 开始时间 {y:2017,m:09,d:10}
   * @param endDate 结束时间
   * @param divide 分隔符
   * @return  '2017.09.01'(默认)
   */
  getTimeStr(startDate, endDate?, divide: string = '.') {
    let y = startDate.y;
    let m = startDate.m + 1;
    let d = startDate.d;
    let text = `${y}${divide}${m < 10 ? '0' + m : m}${divide}${d < 10 ? '0' + d : d}`;
    if (endDate) {
      y = endDate.y;
      m = endDate.m + 1;
      d = endDate.d;
      text = `${text} ~ ${y}${divide}${m < 10 ? '0' + m : m}${divide}${d < 10 ? '0' + d : d}`;
    }
    return text;
  }

  /**
   * @param {Date} time
   * @returns {string} '2017-12-11'
   */
  dateTostr(time: Date) {
    const string = `${time.getFullYear()}-${(time.getMonth() + 1) > 9 ? time.getMonth() +
      1 : '0' + (time.getMonth() + 1)}-${time.getDate() > 9 ? time.getDate() : '0' + time.getDate()}`;
    return string;
  }

  encodeUri(uri: string): string {
    return encodeURI(uri);
  }

  decodeUri(uri: string): string {
    return decodeURI(uri);
  }
  /**
   * @desc 返回初始日期 +- 天数 之后的日期
   * @param {Date} now
   * @param {number} day
   * @returns {Date}
   */
  nextDay(now: Date, day: number): Date {
    return new Date(now.getFullYear(), now.getMonth(), now.getDate() + day);
  }

  /**
   * @Description 弹出框,只有一个确认按钮
   * @param message  // 提示语
   * @param cancelCallback  // 确认的回调
   */
  presentOnceConfirm(message: string, confirmCallback?, rightText?) {
    if (document.getElementsByClassName('seed-confirm-bg').length > 0 || document.getElementsByClassName('seed-present-bg').length > 0) {
      return;
    }
    const rText = rightText || '确 定';
    const confirmBg = document.createElement('div');
    confirmBg.className = 'seed-confirm-bg';
    const bodyTop = document.getElementsByTagName('body')[0];
    const seedConfirm = document.createElement('div');
    seedConfirm.className = 'seed-confirm';

    seedConfirm.innerHTML = `
          <div class="seed-confirm-box">
            <div class="confirm-title"></div>
            <div class="confirm-button">
              <div class="confirm-sure">${rText}</div>
            </div>
          </div>
        `;
    bodyTop.appendChild(confirmBg);
    bodyTop.appendChild(seedConfirm);
    document.getElementsByClassName('confirm-title')[0].innerHTML = message;
    const removeChild = function (event) {
      if (event.target.className === 'confirm-sure') {
        if (confirmCallback) {
          confirmCallback();
        }
      }
      bodyTop.removeChild(confirmBg);
      bodyTop.removeChild(seedConfirm);

    };

    const confrimYes = document.getElementsByClassName('confirm-sure')[0];
    confrimYes.addEventListener('click', removeChild, false);
  }


}
